package com.aizhixin.lab.tets;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.aizhixin.lab.model.PoiModel;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class ExcelTest {
    /**
     * @param headers 标题集合 tilte的长度应该与list中的model的属性个数一致
     * @param dataset 内容集合
     * @param mergeColumns 合并单元格的列
     */
    public static String createExcel(String[] headers, List<Map<String, String>> dataset, String[] mergeColumns) {
        if (headers.length==0){
            return null;
        }
        /*初始化excel模板*/
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setWrapText(true);//设置自动换行
        cellStyle.setFillForegroundColor((short) 13);// 设置背景色
        cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
        cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
        cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
        cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
        Sheet sheet = null;
        try {
            sheet = workbook.createSheet();
        }catch (Exception e){
            e.printStackTrace();
        }

        /*初始化head，填值标题行（第一行）*/
        Row row0 = sheet.createRow(0);
        for(int i = 0; i < headers.length; i++){
            /*创建单元格，指定类型*/
            Cell cell_1 = row0.createCell(i, Cell.CELL_TYPE_STRING);
            cell_1.setCellValue(headers[i]);
        }

        List<PoiModel> poiModels = new ArrayList<PoiModel>();
        Iterator<Map<String, String>> iterator = dataset.iterator();
        int index = 1;	//这里1是从excel的第二行开始，第一行已经塞入标题了
        while (iterator.hasNext()){
            Row row = sheet.createRow(index);
            // 取得当前这行的map，该map中以key，value的形式存着这一行值
            Map<String, String> map = iterator.next();
            // 循环列数，给当前行塞值
            for(int i = 0; i < headers.length; i++) {
                String old = "";
                // old存的是上一行统一位置的单元的值，第一行是最上一行了，所以从第二行开始记
                if(index > 1) {
                    old = poiModels.get(i) == null ? "" : poiModels.get(i).getContent();
                }

                String value = map.get(headers[i]);
                CellRangeAddress cra = null;
                // 循环需要合并的列
                for(int j = 0; j < mergeColumns.length; j++){
                    PoiModel poiModel = null;
                    if(index == 1) {
                        poiModel = new PoiModel();
                        poiModel.setOldContent(value);
                        poiModel.setContent(value);
                        poiModel.setRowIndex(1);
                        poiModel.setCellIndex(i);
                        poiModels.add(poiModel);
                        old = value;
                        break;
                    }
                    poiModel = poiModels.get(i);

                    int rowStartIndex = poiModel.getRowIndex();
                    int rowEndIndex = index - 1;
                    int cellIndex = poiModel.getCellIndex();
                    String content = poiModel.getContent();
                    String preOldContent = poiModels.get(0).getOldContent();
                    String preValue = map.get(headers[0]);
                    Boolean isHeaderEquals = mergeColumns[j].equals(headers[i]);

                    if(i == 0 && isHeaderEquals && !content.equals(value)) {
                        if (rowStartIndex != rowEndIndex) {
                            cra=new CellRangeAddress(rowStartIndex, rowEndIndex, cellIndex, cellIndex);
                            sheet.addMergedRegion(cra);
                        }
                        // 重新记录该列的内容为当前内容，行标记改为当前行标记
                        poiModel.setContent(value);
                        poiModel.setRowIndex(index);
                        poiModel.setCellIndex(i);
                    } else if (i > 0 && isHeaderEquals) {
                        if(!content.equals(value) || (content.equals(value) && !preOldContent.equals(preValue))) {
                            if (rowStartIndex != rowEndIndex) {
                                cra = new CellRangeAddress(rowStartIndex, rowEndIndex, cellIndex, cellIndex);
                                sheet.addMergedRegion(cra);
                            }
                            poiModels.get(i).setContent(value);
                            poiModels.get(i).setRowIndex(index);
                            poiModels.get(i).setCellIndex(i);
                        }
                    }
                    if(isHeaderEquals && index == dataset.size()) {
                        if (i == 0) {
                            if (content.equals(value)) {
                                cra = new CellRangeAddress(rowStartIndex, index, cellIndex, cellIndex);
                                sheet.addMergedRegion(cra);
                            }
                        } else if (i > 0) {
                            if (content.equals(value) && preOldContent.equals(preValue)) {
                                cra = new CellRangeAddress(rowStartIndex, index, cellIndex, cellIndex);
                                sheet.addMergedRegion(cra);
                            }
                        }
                    }
                }
                Cell cell = row.createCell(i, Cell.CELL_TYPE_STRING);
                cell.setCellValue(value);
                // 在每一个单元格处理完成后，把这个单元格内容设置为old内容
                poiModels.get(i).setOldContent(old);
            }
            index++;
        }

        /*生成临时文件*/
        FileOutputStream out = null;
        String localPath = null;
        File tempFile = null;
        String fileName = String.valueOf(new Date().getTime()/1000);
        try {
            tempFile = File.createTempFile(fileName, ".xlsx");
            localPath = tempFile.getAbsolutePath();
            out = new FileOutputStream(localPath);
            workbook.write(out);
        } catch (IOException e){
            e.printStackTrace();
        } finally {
            try {
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return localPath;
    }

//    public static void main(String[] args) {
//        System.out.println(12);
//    }

//    public static void main(String[] args) throws IOException{
//        String[] headers = {"岗位","岗位技能", "模块", "任务", "工单","难度","课时","知识点"};
//        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
//
//        Map<String, String> map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块一");
//        map.put("任务","任务一");
//        map.put("工单","工单一");
//        map.put("难度","困难");
//        map.put("课时","10");
//        map.put("知识点","1.中央处理器（CPU）\n" +
//                "2.二进制工作特点\n" +
//                "3.数据的单位\n" +
//                "4.类的基本原理");
//        list.add(map);
//        map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块一");
//        map.put("任务","任务一");
//        map.put("工单","工单二");
//        map.put("难度","困难");
//        map.put("课时","8");
//        map.put("知识点","1.中央处理器（CPU）\n" +
//                "2.二进制工作特点\n" +
//                "3.数据的单位\n" +
//                "4.类的基本原理");
//        list.add(map);
//        map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块一");
//        map.put("任务","任务一");
//        map.put("工单","工单三");
//        map.put("难度","简单");
//        map.put("课时","6");
//        map.put("知识点","1.中央处理器（CPU）\n" +
//                "2.二进制工作特点\n" +
//                "3.数据的单位\n" +
//                "4.类的基本原理");
//        list.add(map);
//        map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块一");
//        map.put("任务","任务二");
//        map.put("工单","工单一");
//        map.put("难度","简单");
//        map.put("课时","6");
//        map.put("知识点","1.中央处理器（CPU）\n" +
//                "2.二进制工作特点\n" +
//                "3.数据的单位\n" +
//                "4.类的基本原理");
//        list.add(map);
//        map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块一");
//        map.put("任务","任务二");
//        map.put("工单","工单二");
//        map.put("难度","简单");
//        map.put("课时","6");
//        map.put("知识点","1.中央处理器（CPU）\n" +
//                "2.二进制工作特点\n" +
//                "3.数据的单位\n" +
//                "4.类的基本原理");
//        list.add(map);
//        map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块一");
//        map.put("任务","任务二");
//        map.put("工单","工单三");
//        map.put("难度","简单");
//        map.put("课时","6");
//        map.put("知识点","1.中央处理器（CPU）\n" +
//                "2.二进制工作特点\n" +
//                "3.数据的单位\n" +
//                "4.类的基本原理");
//        list.add(map);
//        map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块二");
//        map.put("任务","任务一");
//        map.put("工单","工单一");
//        map.put("难度","困难");
//        map.put("课时","10");
//        map.put("知识点","1.中央处理器（CPU）\n" +
//                "2.二进制工作特点\n" +
//                "3.数据的单位\n" +
//                "4.类的基本原理");
//        list.add(map);
//        map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块二");
//        map.put("任务","任务一");
//        map.put("工单","工单二");
//        map.put("难度","中等");
//        map.put("课时","5");
//        map.put("知识点","1.中央处理器（CPU）\n" +
//                "2.二进制工作特点\n" +
//                "3.数据的单位\n" +
//                "4.类的基本原理");
//        list.add(map);
//        map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块二");
//        map.put("任务","任务二");
//        map.put("工单","工单一");
//        map.put("难度","简单");
//        map.put("课时","2");
//        map.put("知识点","1.字符编码\n" +
//                "2.程序设计语言");
//        list.add(map);
//        map = new HashMap<String, String>();
//        map.put("岗位","前端工程师");
//        map.put("岗位技能","一、任职资格\n" +
//                "1、技能要求\n" +
//                "（1）熟练掌握 HTML技术\n" +
//                "（2）理解并掌握JavaScript语言\n" +
//                "（3）熟练掌握React框架技术\n" +
//                "（4）熟练掌握Vue\n" +
//                "2、可迁移技能\n" +
//                "（1）具有良好的逻辑思维能力、沟通能力、团队合作能力\n" +
//                "（2）具备需求分析、系统设计、数据库设计能力\n" +
//                "\n" +
//                "二、岗位职责\n" +
//                "1. 熟练掌握 HTML技术\n" +
//                "2. 理解并掌握JavaScript语言\n" +
//                "3. 熟练掌握React框架技术");
//        map.put("模块","模块二");
//        map.put("任务","任务二");
//        map.put("工单","工单二");
//        map.put("难度","简单");
//        map.put("课时","6");
//        map.put("知识点","1.字符编码\n" +
//                "2.程序设计语言");
//        list.add(map);
//        String[] regions = new String[]{"岗位","岗位技能", "模块", "任务", "工单","难度","课时","知识点"};
//        System.out.println(createExcel(headers, list, regions));
//    }
}
